Code for getting the grandparent of an object?

I've got a script that will return the parent of an object, but am struggling with how to call a grandparent or great-grandparent. This is for a separate layout column from Main that will show Object Number and Object Heading if Object Heading exists. I do need the data in a separate column so simply filtering with ancestors is not an option.

Many Thanks

string s = null
string p = null

Object o = obj
Object po = parent o

if (po == null) {
s = probeRichAttr_(o,"Object Number", false)
p = o."Object Heading"
displayRich s " " p
}

if (po != null) {

s = probeRichAttr_(po,"Object Number", false)
p = po."Object Heading"
displayRich s " " p

}
SystemAdmin - Fri Mar 15 15:12:19 EDT 2013

Re: Code for getting the grandparent of an object?
SystemAdmin - Fri Mar 15 15:14:01 EDT 2013

forgot to add I may need to call Object Headings from as far away as 4 levels. eg, If Object Heading at Level 3, I'd like to be able to show the heading for an Object Text at Level 7 in a separate column than Main.

Thanks

Re: Code for getting the grandparent of an object?
kbmurphy - Fri Mar 15 15:59:04 EDT 2013

SystemAdmin - Fri Mar 15 15:14:01 EDT 2013
forgot to add I may need to call Object Headings from as far away as 4 levels. eg, If Object Heading at Level 3, I'd like to be able to show the heading for an Object Text at Level 7 in a separate column than Main.

Thanks

Your example seems backwards. I think you meant to say that if an object is at level 7 you'd like to display its level 3 heading.

This may be unhelpful, but I think you should try to solve this yourself using a recursive function. What you're asking for isn't that hard, but if you've never done it before and you figure out how to do it you will learn a lot. If someone just gives you the answer you won't learn anything.

I'll give you a hint: the function you call will take two parameters: an Object and an int. The int represents the number of levels up to go.

Good luck.

Re: Code for getting the grandparent of an object?
kbmurphy - Fri Mar 15 16:00:49 EDT 2013

kbmurphy - Fri Mar 15 15:59:04 EDT 2013
Your example seems backwards. I think you meant to say that if an object is at level 7 you'd like to display its level 3 heading.

This may be unhelpful, but I think you should try to solve this yourself using a recursive function. What you're asking for isn't that hard, but if you've never done it before and you figure out how to do it you will learn a lot. If someone just gives you the answer you won't learn anything.

I'll give you a hint: the function you call will take two parameters: an Object and an int. The int represents the number of levels up to go.

Good luck.

Actually I may have typed faster than I could think this through. You could use recursion to do this. But you could also just use a while or a for loop. No need for a recursive function. Still, you'll need a function with two parameters.

Re: Code for getting the grandparent of an object?
SystemAdmin - Fri Mar 15 16:17:24 EDT 2013

kbmurphy - Fri Mar 15 15:59:04 EDT 2013
Your example seems backwards. I think you meant to say that if an object is at level 7 you'd like to display its level 3 heading.

This may be unhelpful, but I think you should try to solve this yourself using a recursive function. What you're asking for isn't that hard, but if you've never done it before and you figure out how to do it you will learn a lot. If someone just gives you the answer you won't learn anything.

I'll give you a hint: the function you call will take two parameters: an Object and an int. The int represents the number of levels up to go.

Good luck.

I know "what" I want to do, I just don't know how to contruct it

//check object's level(?), then check object's parent(level minus 1) for a heading
//if heading, display Object Number & Heading of object's parent found, if heading empty go to next level up and check for heading(1...n)

you're right tho, I did say it backwards.

will sleep on it and see if fresh eyes can get it tomorrow since we're working the weekend on this.

thanks

Re: Code for getting the grandparent of an object?
kbmurphy - Fri Mar 15 17:33:37 EDT 2013

SystemAdmin - Fri Mar 15 16:17:24 EDT 2013
I know "what" I want to do, I just don't know how to contruct it

//check object's level(?), then check object's parent(level minus 1) for a heading
//if heading, display Object Number & Heading of object's parent found, if heading empty go to next level up and check for heading(1...n)

you're right tho, I did say it backwards.

will sleep on it and see if fresh eyes can get it tomorrow since we're working the weekend on this.

thanks

Well if it helps you did say the exact thing needed to do it. Here's the code in a paragraph form.

Do a for loop where the beginning of the loop starts at 7, and the condition for the end of the loop is i==3, and at the end of the loop decrement by 1. In the loop get the parent of the object. Simple, yet effective. You just have to substitute 7 for the current level and 3 for the desired level.

Get some sleep and refresh your brain. Good luck.

Re: Code for getting the grandparent of an object?
kbmurphy - Fri Mar 15 17:35:03 EDT 2013

kbmurphy - Fri Mar 15 17:33:37 EDT 2013
Well if it helps you did say the exact thing needed to do it. Here's the code in a paragraph form.

Do a for loop where the beginning of the loop starts at 7, and the condition for the end of the loop is i==3, and at the end of the loop decrement by 1. In the loop get the parent of the object. Simple, yet effective. You just have to substitute 7 for the current level and 3 for the desired level.

Get some sleep and refresh your brain. Good luck.

My example was easier than your example -- and it's not exactly what you want. A for loop isn't as good as a while loop. Look up the break statement. A while loop and a break statement is what you need.

Re: Code for getting the grandparent of an object?
SystemAdmin - Sat Mar 16 08:47:43 EDT 2013

kbmurphy - Fri Mar 15 17:35:03 EDT 2013
My example was easier than your example -- and it's not exactly what you want. A for loop isn't as good as a while loop. Look up the break statement. A while loop and a break statement is what you need.

so here's what I've got so far, it's still only doing parents one level up, and not grandparents. Another hint?

//STILL VERY MUCH IN WORK
//STILL ONLY DOING PARENTS, NOT GRANDPARENTS
 
string s = null 
string p = null
 
//set up object and object's parent
Object o = obj
string oh = o."Object Heading"
Object po = parent o
 
//set up the count for level of object 10 is the lowest
//we'll start at 10 then check up the tree
int i = 10 
 
while (i > 0){
//check parent object heading
    if (oh == null){  //check if current object's heading is empty, don't want to do headers
        p = po."Object Heading"
 
        //check if parent object heading is not empty
        if (p != null) {
        s = probeRichAttr_(po,"Object Number", false)
        q = probeRichAttr_(po,"Object Heading", false)
        displayRich s " " q
        break
        }                     //endof parent not empty
 
        //if parent object heading empty go to next level       
        if (p == null) {
                i-- //decrement integer
                break
        }                     //endof parent empty
        }                     //endof current object heading empty
        break                   //break out of while loop when heading found
}                             //endof while(true)


Thanks

Re: Code for getting the grandparent of an object?
SystemAdmin - Sat Mar 16 09:17:37 EDT 2013

Do you mean? ...
 

Object o = obj
Object po = parent o
Object gpo = parent po

Re: Code for getting the grandparent of an object?
SystemAdmin - Sat Mar 16 10:29:17 EDT 2013

SystemAdmin - Sat Mar 16 09:17:37 EDT 2013

Do you mean? ...
 

Object o = obj
Object po = parent o
Object gpo = parent po

I don't think so b/c that would only in effect, check 2 levels up (parent and grandparent). I need to check from as far down as an object may exist (up to 10?) up to it's parent with a heading (section number and title). I believe that's why kbmurphy was suggesting the while loop and the int. Just haven't figured out the construct on the passing of the int value yet.

Re: Code for getting the grandparent of an object?
SystemAdmin - Sat Mar 16 10:44:07 EDT 2013

SystemAdmin - Sat Mar 16 10:29:17 EDT 2013
I don't think so b/c that would only in effect, check 2 levels up (parent and grandparent). I need to check from as far down as an object may exist (up to 10?) up to it's parent with a heading (section number and title). I believe that's why kbmurphy was suggesting the while loop and the int. Just haven't figured out the construct on the passing of the int value yet.

Object objMasterParent = obj;
while (!null(parent(objMasterParent))) { objMasterParent = parent(objMasterParent) }


?

Re: Code for getting the grandparent of an object?
SystemAdmin - Sat Mar 16 11:14:34 EDT 2013

SystemAdmin - Sat Mar 16 10:44:07 EDT 2013

Object objMasterParent = obj;
while (!null(parent(objMasterParent))) { objMasterParent = parent(objMasterParent) }


?

wow, that's way over my head. yes I am quite the noob when it comes to coding dxl, or coding at all for that matter. Will play with after we get past the current deadline. Thanks.

Re: Code for getting the grandparent of an object?
kbmurphy - Sat Mar 16 13:33:42 EDT 2013

SystemAdmin - Sat Mar 16 11:14:34 EDT 2013
wow, that's way over my head. yes I am quite the noob when it comes to coding dxl, or coding at all for that matter. Will play with after we get past the current deadline. Thanks.

I think Wolfgang's example was far too complex, and it doesn't do what you need it to do.

This will get you started. You did well to get as far as you did, you're just missing two or three crucial lines. I did not test this code (it's from the top of my head) but this should do:

Object returnParentObjectAtLevel(int iLevel, Object oGiven) {
 
  Object toReturn = null
 
  //get level of passed object
  int iObjLevel = level oGiven
 
  //error checking: if iLevel >= iObjLevel, we should return null and optionally provide an error
  if (iLevel>=iObjLevel) {
   //print "ERROR: iLevel cannot be greater than the level of the passed object!"
   return null
  }
 
  //do the work
 
 toReturn = oGiven
 
 while (iObjLevel >= iLevel) {
 
   toReturn = parent(toReturn)
  //set new value for iObjLevel
  iObjLevel = level toReturn
 
  //put your if statement here that says if Object Heading != null then break...whatever logic you want
 
 }
 
 return toReturn
}

 


And then to use this in layout:

 

 

 

Object oTemp = returnParentObjectAtLevel(3, obj)
 
if (oTemp != null) {
 display number(oTemp) " " oTemp."Object Heading" ""
}

 

 

Re: Code for getting the grandparent of an object?
llandale - Sat Mar 16 15:21:23 EDT 2013

I'm thinking that when you say "parent" you mean the "Object Heading" under which this object is seen when the module is viewed in Standard view. Thus the "parent" of object "1 Scope" is "Scope". And I think "grand parent" is the "Object Heading" above this object's "parent" heading.

  • Head A
    • text
    • Head B
      • text
        • X text
      • Head C with Y text

If so,

  • the "parent" of "X text" is "Head B" and grand parent is "Head A".
  • the "parent" of "Head C" is "Head C" and grand parent is "Head B".
Object GetParent(Object in_obj)
{  if (null in_obj)  return(Object null)
   string Head = probeAttr_(in_obj, "Object Heading")
   if (!null Head) //
   then return(in_obj)
   else return(GetParent(parent(in_obj)) // ** RECURSION **
}
Object oCurr = current
Object oParent = GetParent(oCurr)
Object oGrandParent = GetParent(parent(oParent))  // check for null oParent first


If an object with Heading is NOT to be its own "parent", change the 2nd to last line to:

 

  • Object oParent = GetParent(parent(oCurr))


-Louie

 

Re: Code for getting the grandparent of an object?
SystemAdmin - Wed Mar 20 15:25:29 EDT 2013

SystemAdmin - Sat Mar 16 11:14:34 EDT 2013
wow, that's way over my head. yes I am quite the noob when it comes to coding dxl, or coding at all for that matter. Will play with after we get past the current deadline. Thanks.

Object objMasterParent = obj;
while (!null(parent(objMasterParent))) { 
    int iLevel = level(objMasterParent);
        int iAbsNum = objMasterParent."Absolute Number";
        string sObjectText = objMasterParent."Object Text";
        string sObjectHeading = objMasterParent."Object Heading";
        string sMessage = "";
        if (sObjectText = "") { 
                sMessage = "Text-Object " iAbsNum " found on level " iLevel " Text:" sObjectText;
        } else {
                sMessage = "Heading-Object " iAbsNum " found on level " iLevel " Heading:" sObjectText;
        }
        print sMessage "\n";
        objMasterParent = parent(objMasterParent) 
}


?

Re: Code for getting the grandparent of an object?
SystemAdmin - Thu Mar 21 08:26:15 EDT 2013

SystemAdmin - Wed Mar 20 15:25:29 EDT 2013

Object objMasterParent = obj;
while (!null(parent(objMasterParent))) { 
    int iLevel = level(objMasterParent);
        int iAbsNum = objMasterParent."Absolute Number";
        string sObjectText = objMasterParent."Object Text";
        string sObjectHeading = objMasterParent."Object Heading";
        string sMessage = "";
        if (sObjectText = "") { 
                sMessage = "Text-Object " iAbsNum " found on level " iLevel " Text:" sObjectText;
        } else {
                sMessage = "Heading-Object " iAbsNum " found on level " iLevel " Heading:" sObjectText;
        }
        print sMessage "\n";
        objMasterParent = parent(objMasterParent) 
}


?

I've got the following doing what I want to do: show the parent object number and heading of the current object. It only shows the first parent then kicks out, so it does not show all the parents up the chain like the ancestors function would in a filter.

Many thanks to you guys for all your ideas and help.
 

//This script will give the parent number and heading of the current object in a layout
//dxl column
 
string s = null 
string p = null
 
//master object for loop
Object objMasterParent = obj
 
//while master object is not empty
while (!null(parent(objMasterParent))) { 
    int iLevel = level(objMasterParent)
        int iAbsNum = objMasterParent."Absolute Number"
 
        string sObjectText =   objMasterParent."Object Text"
        string sObjectHeading = objMasterParent."Object Heading"
        string sMessage = ""
 
//if object text of master object is empty
        if (sObjectText == "") { 
 
                s = probeRichAttr_(objMasterParent,"Object Number", false)
                p = sObjectHeading
                displayRich "Section: " s " " p
                
//we only want the one level up heading(parent) of the object, not all the way like ancestors in a filter so kick out if we've got it       
        break
        } else {
 
        }
 
        objMasterParent = parent(objMasterParent) 
}

 


interestingly enough, I was unable to call Object Number in the same fashion as Object Text and Heading. When I tried to add

 

 

string sObjectNumber =   objMasterParent."Object Number"



It would check ok, but I got an error in the layout column and a message referencing that line. So I just called it as shown above then it worked. No ideas off the top of my head why, but it's doing what I wanted so thanks again guys for all your ideas and help.

Rich



 

Re: Code for getting the grandparent of an object?
SystemAdmin - Thu Mar 21 09:43:31 EDT 2013

SystemAdmin - Thu Mar 21 08:26:15 EDT 2013

I've got the following doing what I want to do: show the parent object number and heading of the current object. It only shows the first parent then kicks out, so it does not show all the parents up the chain like the ancestors function would in a filter.

Many thanks to you guys for all your ideas and help.
 

//This script will give the parent number and heading of the current object in a layout
//dxl column
 
string s = null 
string p = null
 
//master object for loop
Object objMasterParent = obj
 
//while master object is not empty
while (!null(parent(objMasterParent))) { 
    int iLevel = level(objMasterParent)
        int iAbsNum = objMasterParent."Absolute Number"
 
        string sObjectText =   objMasterParent."Object Text"
        string sObjectHeading = objMasterParent."Object Heading"
        string sMessage = ""
 
//if object text of master object is empty
        if (sObjectText == "") { 
 
                s = probeRichAttr_(objMasterParent,"Object Number", false)
                p = sObjectHeading
                displayRich "Section: " s " " p
                
//we only want the one level up heading(parent) of the object, not all the way like ancestors in a filter so kick out if we've got it       
        break
        } else {
 
        }
 
        objMasterParent = parent(objMasterParent) 
}

 


interestingly enough, I was unable to call Object Number in the same fashion as Object Text and Heading. When I tried to add

 

 

string sObjectNumber =   objMasterParent."Object Number"



It would check ok, but I got an error in the layout column and a message referencing that line. So I just called it as shown above then it worked. No ideas off the top of my head why, but it's doing what I wanted so thanks again guys for all your ideas and help.

Rich



 

Object Number, Object Level and Object Identifier are not real attributes, to access those values directly with native DXL commands (the probeRichAttr_ is a library function) you have to use number, level and identifier "perms".

  • Pekka Mäkinen - http://www.softqa.eu/

Re: Code for getting the grandparent of an object?
SystemAdmin - Thu Mar 21 12:56:35 EDT 2013

SystemAdmin - Thu Mar 21 09:43:31 EDT 2013
Object Number, Object Level and Object Identifier are not real attributes, to access those values directly with native DXL commands (the probeRichAttr_ is a library function) you have to use number, level and identifier "perms".

  • Pekka Mäkinen - http://www.softqa.eu/

Good to know, thanks.